package com.music.glide.load.engine.bitmap_recycle

import android.graphics.Bitmap
import com.music.glide.util.Util

/**
 * 用于管理可复用 Bitmap 对象的 AttributeStrategy 策略。
 * 该策略要求返回的 Bitmap 的尺寸和配置（Bitmap.Config）必须严格匹配请求的参数
 */
class KAttributeStrategy : KLruPoolStrategy {

    private val keyPool by lazy { KeyPool() }

    private val groupMap by lazy { KGroupLinkedMap<Key, Bitmap>() }


    override fun put(bitmap: Bitmap) {
        groupMap.put(keyPool.get(bitmap.width, bitmap.height, bitmap.config), bitmap)
    }

    override fun get(width: Int, height: Int, config: Bitmap.Config):Bitmap? {
        return groupMap.get(keyPool.get(width, height, config))
    }

    override fun removeLast(): Bitmap? {
       return groupMap.removeLast()
    }

    override fun logBitmap(bitmap: Bitmap): String {
        return getBitmapString(bitmap)
    }

    override fun logBitmap(width: Int, height: Int, config: Bitmap.Config?):String {
        return getBitmapString(width,height,config)
    }

    override fun getSize(bitmap: Bitmap):Int {
        return Util.getBitmapByteSize(bitmap)
    }

    companion object {

        fun getBitmapString(bitmap: Bitmap): String {
            return getBitmapString(bitmap.width, bitmap.height, bitmap.config)
        }

        fun getBitmapString(width: Int, height: Int, config: Bitmap.Config?): String {
            return "[${width}x${height}], $config"
        }
    }

    class KeyPool : KBaseKeyPool<Key>() {

        fun get(width: Int, height: Int, config: Bitmap.Config): Key {
            return get().apply {
                init(width, height, config)
            }
        }

        override fun create(): Key {
            return Key(this)
        }
    }

    class Key(private val keyPool: KeyPool) : KPoolAble {

        private var width = 0

        private var height = 0

        private var config: Bitmap.Config? = null



        fun init(width: Int, height: Int, config: Bitmap.Config) {
            this.width = width
            this.height = height
            this.config = config
        }

        override fun toString(): String {
            return getBitmapString(width, height, config)
        }

        override fun offer() {
            keyPool.offer(this)
        }

        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false

            other as Key

            if (width != other.width) return false
            if (height != other.height) return false
            if (config != other.config) return false

            return true
        }

        override fun hashCode(): Int {
            var result = width
            result = 31 * result + height
            result = 31 * result + (config?.hashCode() ?: 0)
            return result
        }
    }
}